
#ifndef H_C_RB_TREE_H
#define H_C_RB_TREE_H

#include "ctypes.h"
#include "citerator.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef enum ERbtNodeColor{
	ERNC_BLACK, 
	ERNC_RED
}ERbtNodeColor;

typedef struct tagSRbtNode{
	struct tagSRbtNode* pstParent;
	struct tagSRbtNode* pstLeft;
	struct tagSRbtNode* pstRight;
	ERbtNodeColor       eRbtNodeColor;
	char                pcValue[1];
}SRbtNode, *PSRbtNode;

typedef struct tagSRbTree{
	EContainerType  eContainerType;
	SStlcType       stStlcType;  
	SRbtNode        stRbtNode;
	size_t          szNodeCnt;	
}SRbTree, *PSRbTree;

STLCDLL_EXPORTS SRbTree   StlcRbTreeCreate( size_t a_szTypeSize, const char* a_pcTypeName );
STLCDLL_EXPORTS void      StlcRbTreeInit( PSRbTree a_pstRbTree, PFCompare a_pfnCompare, PFDestroy a_pfnDestroy );
STLCDLL_EXPORTS void      StlcRbTreeClear( PSRbTree a_pstRbTree );
STLCDLL_EXPORTS void      StlcRbTreeDestroy( PSRbTree a_pstRbTree );
STLCDLL_EXPORTS void      StlcRbTreeInitCopy( PSRbTree a_pstRbTreeDest, const SRbTree* a_pstRbTreeSrc );
STLCDLL_EXPORTS void      StlcRbTreeInitCopyRange( PSRbTree a_pstRbTree, const SIterator a_stIteratorBegin, const SIterator a_stIteratorEnd );

STLCDLL_EXPORTS bool      StlcRbTreeSameType( const SRbTree* a_pstRbTreeFirst, const SRbTree* a_pstRbTreeSecond );
STLCDLL_EXPORTS void      StlcRbTreeAssign( PSRbTree a_pstRbTreeDest, const SRbTree* a_pstRbTreeSrc );

STLCDLL_EXPORTS size_t    StlcRbTreeSize( const SRbTree* a_pstRbTree );
STLCDLL_EXPORTS bool      StlcRbTreeEmpty( const SRbTree* a_pstRbTree );
STLCDLL_EXPORTS size_t    StlcRbTreeMaxSize( const SRbTree* a_pstRbTree );

STLCDLL_EXPORTS SIterator StlcRbTreeBegin( const SRbTree* a_pstRbTree );
STLCDLL_EXPORTS SIterator StlcRbTreeEnd( const SRbTree* a_pstRbTree );

STLCDLL_EXPORTS size_t    StlcRbTreeCount( const SRbTree* a_pstRbTree, const void* a_pValue );
STLCDLL_EXPORTS SIterator StlcRbTreeFindPos( const SRbTree* a_pstRbTree, const void *a_pKey );
STLCDLL_EXPORTS SIterator StlcRbTreeFindPosN( const SRbTree* a_pstRbTree, const void *a_pKey, size_t a_szIndex );


STLCDLL_EXPORTS SIterator StlcRbTreeLowerBound(	const SRbTree* a_pstRbTree, const void* a_pValue );
STLCDLL_EXPORTS SIterator StlcRbTreeUpperBound(	const SRbTree* a_pstRbTree, const void* a_pValue );
STLCDLL_EXPORTS bool      StlcRbTreeEqual( const SRbTree* a_pstRbTreeFirst, const SRbTree* a_pstRbTreeSecond );
STLCDLL_EXPORTS bool      StlcRbTreeNotEqual( const SRbTree* a_pstRbTreeFirst, const SRbTree* a_pstRbTreeSecond );
STLCDLL_EXPORTS bool      StlcRbTreeLess( const SRbTree* a_pstRbTreeFirst, const SRbTree* a_pstRbTreeSecond );
STLCDLL_EXPORTS bool      StlcRbTreeGreat( const SRbTree* a_pstRbTreeFirst, const SRbTree* a_pstRbTreeSecond );
STLCDLL_EXPORTS bool      StlcRbTreeLessEqual( const SRbTree* a_pstRbTreeFirst, const SRbTree* a_pstRbTreeSecond );
STLCDLL_EXPORTS bool      StlcRbTreeGreatEqual( const SRbTree* a_pstRbTreeFirst, const SRbTree* a_pstRbTreeSecond );
STLCDLL_EXPORTS void      StlcRbTreeSwap( PSRbTree a_pstRbTreeFirst, PSRbTree a_pstRbTreeSecond );

STLCDLL_EXPORTS SIterator StlcRbTreeInsertEqual( PSRbTree a_pstRbTree, const void* a_pValue );
STLCDLL_EXPORTS SIterator StlcRbTreeInsertUnique( PSRbTree a_pstRbTree, const void* a_pValue );

STLCDLL_EXPORTS void      StlcRbTreeInsertEqualRange( PSRbTree a_pstRbTree, SIterator a_stIterBegin, const SIterator a_stIterEnd );
STLCDLL_EXPORTS void      StlcRbTreeInsertUniqueRange( PSRbTree a_pstRbTree, SIterator a_stIterBegin, const SIterator a_stIterEnd );

STLCDLL_EXPORTS SIterator StlcRbTreeErase( PSRbTree a_pstRbTree, const void* a_pValue );
STLCDLL_EXPORTS SIterator StlcRbTreeErasePos( PSRbTree a_pstRbTree, SIterator a_stIterator );
STLCDLL_EXPORTS SIterator StlcRbTreeEraseRange(	PSRbTree a_pstRbTree, SIterator a_stIterBegin, const SIterator a_stIterEnd );


STLCDLL_EXPORTS SIterator   StlcRbTreeIteratorCreate(void);
STLCDLL_EXPORTS bool        StlcRbTreeIteratorBelongTo( const SRbTree* a_pstRbTree, const SIterator a_stIterator );
STLCDLL_EXPORTS bool        StlcRbTreeIteratorEqual( const SRbTree* a_pstRbTree, const SIterator a_stIterFirst, const SIterator a_stIterSecond );
STLCDLL_EXPORTS void        StlcRbTreeIteratorGetValue( const SRbTree* a_pstRbTree, const SIterator a_stIterator, void* a_pValue );
STLCDLL_EXPORTS const void* StlcRbTreeIteratorGetPointer( const SRbTree* a_pstRbTree, const SIterator a_stIterator );
STLCDLL_EXPORTS void        StlcRbTreeIteratorNext( const SRbTree* a_pstRbTree, PSIterator a_pstIterator );
STLCDLL_EXPORTS void        StlcRbTreeIteratorPrev( const SRbTree* a_pstRbTree, PSIterator a_pstIterator );
STLCDLL_EXPORTS void        StlcRbTreeIteratorNextN( const SRbTree* a_pstRbTree, PSIterator a_pstIterator, int a_nStep );
STLCDLL_EXPORTS void        StlcRbTreeIteratorPrevN( const SRbTree* a_pstRbTree, PSIterator a_pstIterator, int a_nStep );
STLCDLL_EXPORTS int         StlcRbTreeIteratorDistance( const SRbTree* a_pstRbTree, const SIterator a_stIterFirst, const SIterator a_stIterSecond );
STLCDLL_EXPORTS bool        StlcRbTreeIteratorBefore( const SIterator a_stIterFirst, const SIterator a_stIterSecond );

#ifdef __cplusplus
}
#endif

#endif